package com.jwww.support.mybatis.query;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.jwww.support.mybatis.SqlChecker;

/**
 * 通用原生SQL查询对象
 *
 * @author jwww
 * @date 2015年4月17日下午4:34:12
 * @description <br>
 * Copyright (c) 2015, vakinge@gmail.com.
 */
public class NativeQuery {

	private String fields = "*";
	private String where;
	private String orderBy;
	private String join;
	private String updateSet;//更新集合
	

	public String getFields() {
		return fields;
	}

	public NativeQuery fields(String fields) {
		this.fields = fields;
		return this;
	}

	public String getWhere() {
		return where;
	}

	public String getUpdateSet() {
		return updateSet;
	}

	/**
	 * 设置查询条件<br>
	 * LIKE:where("name = ? and age = ? and status in (?)", "a",3,list)
	 *
	 * @param where
	 * @param params
	 * @return
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	public NativeQuery where(String where, Object... params) {
		if (params != null) {
			//int condiCount = where.length() - where.replaceAll("\\?", "").length();
			//if (condiCount != params.length) throw new RuntimeException("查询条件通配符和参数个数不匹配");
			//in 
			for (Object param : params) {
				if (param instanceof Collection) {
					param = buildSqlIn((Collection) param);
					where = where.replaceFirst("\\?", param.toString());
				} else {
					where = where.replaceFirst("\\?", "'" + SqlChecker.paramsSafeFilter(param.toString()) + "'");
				}
			}
		}
		this.where = where;
		return this;
	}
	
	/**
	 * 设置更新字段集合
	 * @param expr
	 * @param params
	 * @return
	 */
	public NativeQuery set(String expr, Object... params) {
		if (params != null) {
			int condiCount = expr.length() - expr.replaceAll("\\?", "").length();
			if (condiCount != params.length) throw new RuntimeException("查询条件通配符和参数个数不匹配");
			//in 
			for (Object param : params) {
				expr = expr.replaceFirst("\\?", "'" + SqlChecker.paramsSafeFilter(param.toString()) + "'");
			}
		}
		this.updateSet = expr;
		return this;
	}

	public String getOrderBy() {
		return orderBy;
	}

	public NativeQuery orderBy(String orderBy) {
		this.orderBy = orderBy;
		return this;
	}

	public String getJoin() {
		return join;
	}

	public NativeQuery join(String join) {
		this.join = join;
		return this;
	}

	public NativeQuery count(String field) {
		if (StringUtils.isBlank(field)) field = "*";
		this.fields = "COUNT(" + field + ")";
		return this;
	}
	
	public NativeQuery sum(String field) {
		this.fields = "IFNULL(SUM("+field +"),0)";
		return this;
	}

	public NativeQuery max(String field) {
		this.fields = "IFNULL(MAX("+field +"),0)";
		return this;
	}
	
	public NativeQuery min(String field) {
		this.fields = "IFNULL(MIN("+field +"),0)";
		return this;
	}
	
	public NativeQuery avg(String field) {
		this.fields = "IFNULL(AVG("+field +"),0)";
		return this;
	}

	private static String buildSqlIn(Collection<Object> list) {
		StringBuffer sb = new StringBuffer();
		if (list !=null && !list.isEmpty()) {
			for (Object object : list) {
				sb.append("'").append(SqlChecker.paramsSafeFilter(object.toString())).append("',");
			}
			sb.deleteCharAt(sb.length() - 1);
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		List<Object> list = new ArrayList<Object>();
		list.add(1);
		list.add(2);
		NativeQuery query = new NativeQuery().where("name = ? and age = ? and status in (?)", "delete from", 3, Arrays.asList(new String[]{"a", "b", "c"}));
		query.sum("*");
		System.out.println(query.getFields());
		System.out.println(query.getWhere());
	}

}
